package org.meteorshower.config;

import org.meteorshower.service.IAdminService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;

import java.util.Optional;

public class AdminAuthenticationProvider implements AuthenticationProvider {

    private UserDetailsService adminService;
    private PasswordEncoder passwordEncoder;

    public AdminAuthenticationProvider(IAdminService adminService) {
        this(adminService,null);
    }

    public AdminAuthenticationProvider(IAdminService adminService, PasswordEncoder encoder) {
        this.adminService = adminService;
        this.passwordEncoder = encoder;
    }

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        if(!supports(authentication.getClass())){
            throw new BadCredentialsException("不支持的认证方式");
        }
        String requestUsername = (String) authentication.getPrincipal();
        String requestPassword = (String) authentication.getCredentials();
        UserDetails admin = adminService.loadUserByUsername(requestUsername);
        if (admin == null){
            throw new BadCredentialsException("用户不存在");
        }
        boolean condition;
        if (passwordEncoder == null) {
            condition = admin.getPassword().equals(requestPassword);
        }else{
            condition = passwordEncoder.matches(requestPassword,admin.getPassword());
        }
        if (condition){
            //认证通过密码置空
            return new AdminAuthenticationToken(admin.getUsername(),null,admin.getAuthorities());
        }else{
            throw new BadCredentialsException("密码错误");
        }
    }

    /**
     * Token类型判定
     * */
    @Override
    public boolean supports(Class<?> aClass) {
        return AdminAuthenticationToken.class.isAssignableFrom(aClass);
    }
}
